import {
	readFile,
	writeFile,
} from 'node:fs/promises';
import {
	exec,
} from 'node:child_process';
import {
	inc,
	prerelease,
	valid,
} from 'semver';
import {
	select,
	input,
	confirm,
} from '@inquirer/prompts'
import chalk from 'chalk';
import packageJson from '../package.json' with {type:'json'};

const {
	version,
} = packageJson;

//region 步骤打印
function step(msg){
	console.log(chalk.cyan(msg));
}
//endregion
//region 运行命令
function run(cmd){
	return new Promise((resolve, reject) => {
		exec(cmd, (error, stdout, stderr) => {
			if(error){
				reject(error);
			}else{
				console.log(stdout)
				resolve()
			}
		});
	});
}
//endregion
(async () => {
	//region 获取版本号
	const identifier = prerelease(version)?.[0] || 'beta';
	const releaseType = await select({
		message:'请选择你发布版本类型',
		choices:[
			{
				name:'正式版本',
				value:'release',
			},
			{
				name:'测试版本',
				value:'beta',
			},
			{
				name:'手动输入',
				value:'manual',
			},
		],
	})
	const targetVersion
			= releaseType === 'manual'
			? await input({
				message:'请输入版本号',
				default:version,
				required:true,
				prefill:'editable',
			})
			: await select({
				message:'请选择发布版本号',
				choices:(
						releaseType === 'release'
								? [
									'patch',
									'minor',
									'major',
								]
								: [
									'prerelease',
									'prepatch',
									'preminor',
									'premajor',
								]
				).map((type) => {
					const value = inc(version, type, identifier);
					return {
						name:`${type} (${value})`,
						value,
					}
				}),
			});
	if(!valid(targetVersion)){
		throw new Error(`不是有效的版本号: ${targetVersion}`);
	}
	//endregion
	const isConfirm = await confirm({
		message: `发布 v${targetVersion}, 是否继续?`,
		default:true,
	});
	if(!isConfirm){
		return;
	}
	step('更新 package.json');
	const packageStr = await readFile('package.json', {
		encoding:'utf8'
	});
	await writeFile(
		'package.json',
		packageStr.replace(
			new RegExp(`"version":\\s*"${version}"`, 'm'),
			`"version":"${targetVersion}"`,
		),
	);
	step('生成变更日志');
	await run('npm run changelog');
	step('提交代码');
	await run('git add -A');
	await run(`git commit -m "chore(release): ${targetVersion}"`);
	await run(`git tag v${targetVersion}"`);
	step('推送包');
	await run('npm publish');
})();